﻿//------------------------------------------------------------------------------------------------------
// The MIT License (MIT) Copyright (c) 2014 Marton Rusko
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and 
// associated documentation files (the "Software"), to deal in the Software without restriction, 
// including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, 
// and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, 
// subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or substantial 
// portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT 
// LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//------------------------------------------------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.Linq;
using AutoMapper;
using RM.Banking.Common;
using RM.Banking.Unicredit.Statements;

namespace RM.Banking.Unicredit
{
    /// <summary>
    /// Unicredit Statement Processor
    /// </summary>
    public class UnicreditStatementProcessor : BankStatementProcessor
    {
        #region Static constructor 

        /// <summary>
        /// Initialize mapping
        /// </summary>
        static UnicreditStatementProcessor()
        {
            Mapper.CreateMap<UnicreditStatementHeaderRecord, BankStatementProcessingResult>()
                .ForMember(dst => dst.ClientName, opt => opt.MapFrom(src => src.UgyfelNev))
                .ForMember(dst => dst.ClientId, opt => opt.MapFrom(src => src.Szamlaszam))
                .ForMember(dst => dst.ClientTitle, opt => opt.MapFrom(src => src.UgyfelTitulus))
                .ForMember(dst => dst.ClientAddress1, opt => opt.MapFrom(src => src.UgyfelCim1))
                .ForMember(dst => dst.ClientAddress2, opt => opt.MapFrom(src => src.UgyfelCim2))
                .ForMember(dst => dst.ClientAddress3, opt => opt.MapFrom(src => src.UgyfelCim3))
                .ForMember(dst => dst.ClientAddress4, opt => opt.MapFrom(src => src.UgyfelCim4))
                .ForMember(dst => dst.PreviousStatementDate, opt => opt.MapFrom(src => src.ElozoKivonatDatuma))
                .ForMember(dst => dst.StatementDate, opt => opt.MapFrom(src => src.KivonatDatum))
                .ForMember(dst => dst.StatementId,
                           opt => opt.MapFrom(src => string.Format("{0}_{1}", src.Szamlaszam, FormatStatementId(src.KivonatDatum))))
                .ForMember(dst => dst.AccountNumber, opt => opt.MapFrom(src => src.Szamlaszam))
                .ForMember(dst => dst.AccountCurrency, opt => opt.MapFrom(src => src.SzamlaDevizaneme))
                .ForMember(dst => dst.OpenBalance, opt => opt.MapFrom(src => src.Nyitoegyenleg))
                .ForMember(dst => dst.TotalCredit, opt => opt.MapFrom(src => src.OsszesJovairas))
                .ForMember(dst => dst.TotalDebit, opt => opt.MapFrom(src => src.OsszesTerheles))
                .ForMember(dst => dst.ClosingBalance, opt => opt.MapFrom(src => src.Zaroegyenleg));

            Mapper.CreateMap<UnicreditStatementDataRecord, BankStatementProcessingResult>()
                .ForMember(dst => dst.TransactionId, opt => opt.MapFrom(src => string.Format("{0}_{1}_{2}", src.Szamlaszam, FormatStatementId(src.KivonatDatuma), src.TetelSorszama)))
                .ForMember(dst => dst.TransactionIndex, opt => opt.MapFrom(src => src.TetelSorszama))
                .ForMember(dst => dst.AccountingDate, opt => opt.MapFrom(src => src.KonyvelesiNap))
                .ForMember(dst => dst.ValueDate, opt => opt.MapFrom(src => src.Erteknap))
                .ForMember(dst => dst.Amount, opt => opt.MapFrom(src => src.Osszeg))
                .ForMember(dst => dst.Branch, opt => opt.MapFrom(src => src.FiokKodja));

            Mapper.CreateMap<UnicreditStatementWireTransferRecord, BankStatementProcessingResult>();

        }

        #endregion

        #region Helper methods

        private static string FormatStatementId(DateTime kivonatDatum)
        {
            return String.Format("{0:yyyyMMdd}", kivonatDatum);
        }

        #endregion

        #region Overrides of BankStatementProcessor

        /// <summary>
        /// Process statement file data
        /// </summary>
        /// <param name="data">File data bytes</param>
        /// <returns>BankStatementProcessingResult items</returns>
        protected override IEnumerable<BankStatementProcessingResult> ProcessCore(byte[] data)
        {
            var processor = new UnicreditStatementFileProcessor(data);

            var results = processor.Rows.Select(f =>
            {
                var result = Mapper.Map<BankStatementProcessingResult>(processor.Header);
                Mapper.Map(f, result);
                if (f.HasExtension())
                {
                    var wireTransferRecord = f.ExtenderRecord as UnicreditStatementWireTransferRecord;
                    if (wireTransferRecord != null)
                        Mapper.Map(wireTransferRecord, result);
                }

                return result;
            });

            return results.ToArray();
        }

        #endregion
    }
}